package by.kniazhych.core.controllers {
	
	/**
	 * ...
	 * @author Boutylin Mikhail
	 */
	
	import by.kniazhych.core.constants.UserColor;
	import by.kniazhych.core.controllers.actions.ProcessMotionAction;
	import by.kniazhych.core.controllers.actions.ServerActionsFactory;
	import by.kniazhych.core.data.game.GameData;
	import by.kniazhych.core.data.game.PeaceData;
	import by.kniazhych.core.data.game.PeacePosition;
	import by.kniazhych.core.events.GameEvent;
	import by.kniazhych.core.server.common.ClientCommands;
	import by.kniazhych.core.server.common.IServerProxy;
	import by.kniazhych.core.server.common.ServerCommands;
	import by.kniazhych.core.view.frames.BaseFrameView;;
	import by.kniazhych.core.view.game.peace.PeaceView;
	import by.kniazhych.core.view.game.peace.PeaceViewFactory;
	import by.vaukalak.core.commands.Command;
	import by.vaukalak.core.commands.CommandDispatcher;
	import by.vaukalak.core.commands.ICommandDispatcher;
	import by.vaukalak.core.controllers.IBaseController;
	import by.vaukalak.core.data.Data;
	import by.vaukalak.core.data.DataContainer;
	import by.vaukalak.core.utils.applyConstructor;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.geom.Point;
	import flash.utils.Dictionary;
	

	
	public class GameController extends NativeGameController implements ICommandDispatcher{
		
		private var _serverProxy:IServerProxy;
		internal var $peaceLinker:Dictionary = new Dictionary(true);
		private static const LINKER_DELIM:String = ":";
		private var _factory:ServerActionsFactory;
		private var _currentAction:AbstractServerAction;
		private var _color:uint;
		
		public function GameController(baseController:IBaseController, color:uint, serverProxy:IServerProxy) {
			super(baseController);
			_color = color;
			_serverProxy = serverProxy;
			
			_init();
		}
		
		
		private function _init():void {
			
			_factory = new ServerActionsFactory();
			
			_serverProxy.observeClient(this);
			_serverProxy.addCommandListener(ServerCommands.EXECUTE_ACTIONS, _onActionExecuteCommand);
			
			$gameData = new GameData();
			super.dataBase.addChild($gameData);
			
		}
		
		//--------------------------------------------------------------------------
		//
		//  OVERRIDEN METHODS
		//
		//--------------------------------------------------------------------------
		
		override public function enterFrame():void {
			super.enterFrame();
			dispatchCommand(new Command(ClientCommands.CONNECT, ["asd", _color]));
		}
		
		//--------------------------------------------------------------------------
		//
		//  PUBLIC METHODS
		//
		//--------------------------------------------------------------------------
		
		public function buildGame(board:Array, color:uint):void {
			super.$gameData.color = color;
			var peaceFactory:PeaceViewFactory = new PeaceViewFactory();
			super.$gameContainer.observe($gameData);
			for (var i:int = 0; i < board.length; i++) {
				for (var j:int = 0; j < board[i].length; j++) {
					var peaceType:uint = board[i][j];
					if (peaceType) {
						var data:PeaceData = new PeaceData(board[i][j], new PeacePosition(j,i));
						$gameData.addChild(data);
						$peaceLinker[i + LINKER_DELIM + j] = data;
						var view:PeaceView = new PeaceView(data, peaceFactory);
						view.mouseEnabled = view.mouseChildren = (data.color == super.$gameData.color);
						view.addEventListener(GameEvent.PEACE_RELEASED, _onPeaceReleased);
						super.$gameContainer.addPeaceView(view);
					}					
				}
			}
			
		}
		
		//--------------------------------------------------------------------------
		//
		//  EVENT HANDLERS
		//
		//--------------------------------------------------------------------------
		
		private function _onActionExecuteCommand(command:Command):void {
			if(!_currentAction) _executeNextAction();
		}
		
		private function _executeNextAction(e:Event = null):void {
			_currentAction = null;
			if (e) {
				IEventDispatcher(e.target).removeEventListener(e.type, _executeNextAction);
			}
			if (_serverProxy.hasCommandsToExecute()) {
				_currentAction = _factory.generateAction(this, _serverProxy.shiftActionCommand());
				_currentAction.addEventListener(GameEvent.ACTION_PROCESSED, _executeNextAction);
				_currentAction.process();
			}
		}
		
		private function _onPeaceReleased(e:GameEvent):void {
			var target:PeaceView = e.target as PeaceView;
			var position:PeacePosition = $gameContainer.calculatePeaceIndexes(target);
			dispatchCommand(new Command(ClientCommands.MOTION_REQUEST, [target.data.position, position]));
			
		}
		
	}

}